सब-कमांड और कस्टम एक्शन क्लास की उन्नत तकनीकों से पाइथन आर्गपार्स की पूरी क्षमता का उपयोग करें, और अपने कमांड-लाइन इंटरफ़ेस डिज़ाइन और उपयोगकर्ता अनुभव को बेहतर बनाएं।
पाइथन आर्गपार्स एडवांस्ड: सब-कमांड्स और कस्टम एक्शन क्लासेस में महारत हासिल करना
पाइथन का argparse
मॉड्यूल कमांड-लाइन इंटरफेस (CLIs) बनाने के लिए एक शक्तिशाली उपकरण है। जबकि इसका सामान्य उपयोग अपेक्षाकृत सीधा है, argparse
उन्नत सुविधाएँ प्रदान करता है जो परिष्कृत और उपयोगकर्ता-अनुकूल सीएलआई बनाने की अनुमति देती हैं। यह ब्लॉग पोस्ट ऐसी दो उन्नत विशेषताओं पर गहराई से चर्चा करता है: सब-कमांड्स और कस्टम एक्शन क्लासेस।
एडवांस्ड आर्गपार्स क्यों?
केवल कुछ विकल्पों वाले सरल स्क्रिप्ट के लिए, बुनियादी argparse
कार्यक्षमता पर्याप्त हो सकती है। हालाँकि, जैसे-जैसे आपके स्क्रिप्ट जटिलता और कार्यक्षमता में बढ़ते हैं, एक अधिक संरचित और संगठित सीएलआई आवश्यक हो जाता है। उन्नत argparse
सुविधाएँ मदद करती हैं:
- उपयोगकर्ता अनुभव में सुधार करें: उपयोगकर्ताओं के लिए एक स्पष्ट और सहज इंटरफ़ेस प्रदान करें।
- कोड की रखरखाव क्षमता बढ़ाएँ: अपने कोड को तार्किक मॉड्यूल में व्यवस्थित करें, जिससे इसे समझना और बनाए रखना आसान हो जाता है।
- कार्यक्षमता बढ़ाएँ: एक ही स्क्रिप्ट के भीतर जटिल वर्कफ़्लो और कई ऑपरेशनों का समर्थन करें।
- पुन: प्रयोज्यता को बढ़ावा दें: पुन: प्रयोज्य घटक बनाएँ जिन्हें आपके एप्लिकेशन के विभिन्न भागों में लागू किया जा सकता है।
सब-कमांड्स: जटिल सीएलआई को व्यवस्थित करना
सब-कमांड्स संबंधित कमांड्स को एक मुख्य कमांड के तहत समूहित करने का एक तरीका है। यह उन एप्लिकेशनों के लिए विशेष रूप से उपयोगी है जो विभिन्न प्रकार के अलग-अलग कार्य करते हैं। उदाहरण के लिए, Git के बारे में सोचें। यह सब-कमांड्स का बड़े पैमाने पर उपयोग करता है: git commit
, git push
, git pull
, इत्यादि। प्रत्येक सब-कमांड के अपने तर्क और विकल्प होते हैं।
argparse
के साथ सब-कमांड्स लागू करना
argparse
के साथ सब-कमांड लागू करने के लिए, आप add_subparsers()
विधि का उपयोग करते हैं। यहाँ एक मूल उदाहरण है:
import argparse
# Create the main parser
parser = argparse.ArgumentParser(description='A simple example with subcommands')
# Create the subparser
subparsers = parser.add_subparsers(dest='command', help='Available commands')
# Create the 'add' subcommand
add_parser = subparsers.add_parser('add', help='Add two numbers')
add_parser.add_argument('x', type=int, help='First number')
add_parser.add_argument('y', type=int, help='Second number')
# Create the 'subtract' subcommand
subtract_parser = subparsers.add_parser('subtract', help='Subtract two numbers')
subtract_parser.add_argument('x', type=int, help='First number')
subtract_parser.add_argument('y', type=int, help='Second number')
# Parse the arguments
args = parser.parse_args()
# Perform the action based on the subcommand
if args.command == 'add':
result = args.x + args.y
print(f'The sum is: {result}')
elif args.command == 'subtract':
result = args.x - args.y
print(f'The difference is: {result}')
else:
parser.print_help()
इस उदाहरण में:
- हम
argparse.ArgumentParser()
का उपयोग करके एक मुख्य पार्सर बनाते हैं। - हम
parser.add_subparsers(dest='command', help='Available commands')
का उपयोग करके एक सब-पार्सर जोड़ते हैं।dest
तर्क उस विशेषता को निर्दिष्ट करता है जो चुने गए सब-कमांड का नाम संग्रहीत करेगा। - हम
subparsers.add_parser()
का उपयोग करके दो सब-कमांड, 'add' और 'subtract' बनाते हैं। - प्रत्येक सब-कमांड के अपने तर्कों का सेट होता है (
x
औरy
)। - हम
parser.parse_args()
का उपयोग करके तर्कों को पार्स करते हैं। - हम
args.command
के मान की जाँच करते हैं ताकि यह निर्धारित किया जा सके कि कौन सा सब-कमांड चुना गया था और फिर संबंधित कार्रवाई करते हैं।
इस स्क्रिप्ट को चलाने के लिए, आप इस तरह के कमांड का उपयोग करेंगे:
python your_script.py add 5 3
python your_script.py subtract 10 2
उन्नत सब-कमांड तकनीकें
1. सब-कमांड्स को संभालने के लिए फ़ंक्शंस का उपयोग करना
एक अधिक संगठित दृष्टिकोण प्रत्येक सब-कमांड को संभालने के लिए अलग-अलग फ़ंक्शन को परिभाषित करना है। यह कोड की पठनीयता और रखरखाव में सुधार करता है।
import argparse
def add(args):
result = args.x + args.y
print(f'The sum is: {result}')
def subtract(args):
result = args.x - args.y
print(f'The difference is: {result}')
# Create the main parser
parser = argparse.ArgumentParser(description='A simple example with subcommands')
# Create the subparser
subparsers = parser.add_subparsers(dest='command', help='Available commands')
# Create the 'add' subcommand
add_parser = subparsers.add_parser('add', help='Add two numbers')
add_parser.add_argument('x', type=int, help='First number')
add_parser.add_argument('y', type=int, help='Second number')
add_parser.set_defaults(func=add)
# Create the 'subtract' subcommand
subtract_parser = subparsers.add_parser('subtract', help='Subtract two numbers')
subtract_parser.add_argument('x', type=int, help='First number')
subtract_parser.add_argument('y', type=int, help='Second number')
subtract_parser.set_defaults(func=subtract)
# Parse the arguments
args = parser.parse_args()
# Call the function associated with the subcommand
if hasattr(args, 'func'):
args.func(args)
else:
parser.print_help()
यहाँ, हम प्रत्येक सब-कमांड के साथ एक फ़ंक्शन को जोड़ने के लिए set_defaults(func=...)
का उपयोग करते हैं। फिर, पार्सिंग के बाद, हम उपयुक्त फ़ंक्शन को कॉल करते हैं यदि वह मौजूद है।
2. नेस्टिंग सब-कमांड्स
आप और भी जटिल और श्रेणीबद्ध सीएलआई बनाने के लिए सब-कमांड्स को नेस्ट कर सकते हैं। उदाहरण के लिए, क्लाउड संसाधनों के प्रबंधन के लिए एक सीएलआई पर विचार करें:
cloud compute instance create --name my-instance --region us-east-1
cloud storage bucket list --project my-project
इस उदाहरण में, cloud
मुख्य कमांड है, compute
और storage
सब-कमांड हैं, और instance
और bucket
सब-सब-कमांड हैं।
3. वास्तविक दुनिया का उदाहरण: अंतर्राष्ट्रीयकरण उपकरण
एक बहु-भाषी एप्लिकेशन में अनुवादों के प्रबंधन के लिए एक उपकरण की कल्पना करें। आप विभिन्न ऑपरेशनों को व्यवस्थित करने के लिए सब-कमांड का उपयोग कर सकते हैं:
translation tool add-language --code fr_FR --name "French (France)"
translation tool extract-strings --source-dir src
translation tool translate --target-language es_ES --source-file strings.pot
यह दृष्टिकोण चिंताओं का एक स्पष्ट पृथक्करण की अनुमति देता है और उपकरण को उपयोग करने और बनाए रखने में आसान बनाता है, खासकर जब विभिन्न देशों में लागू होने वाले कई भाषाओं और अनुवाद वर्कफ़्लो से निपटते हैं।
कस्टम एक्शन क्लासेस: आर्गुमेंट पार्सिंग को अनुकूलित करना
argparse
आपको यह अनुकूलित करने के लिए कस्टम एक्शन क्लास परिभाषित करने की अनुमति देता है कि तर्कों को कैसे संसाधित किया जाता है। यह उन परिदृश्यों के लिए उपयोगी है जहाँ डिफ़ॉल्ट तर्क प्रसंस्करण व्यवहार पर्याप्त नहीं है। एक एक्शन क्लास एक ऐसी क्लास है जो argparse.Action
से विरासत में मिलती है और __call__
विधि को ओवरराइड करती है।
एक कस्टम एक्शन क्लास बनाना
यहाँ एक कस्टम एक्शन क्लास का एक उदाहरण है जो एक तर्क को अपरकेस में परिवर्तित करता है:
import argparse
class ToUpper(argparse.Action):
def __call__(self, parser, namespace, values, option_string=None):
if isinstance(values, list):
setattr(namespace, self.dest, [v.upper() for v in values])
else:
setattr(namespace, self.dest, values.upper())
# Create the parser
parser = argparse.ArgumentParser(description='Example with custom action')
# Add an argument with the custom action
parser.add_argument('--name', action=ToUpper, help='Name to convert to uppercase')
parser.add_argument('--cities', action=ToUpper, nargs='+', help='List of cities to convert to uppercase')
# Parse the arguments
args = parser.parse_args()
# Print the result
if args.name:
print(f'Name: {args.name}')
if args.cities:
print(f'Cities: {args.cities}')
इस उदाहरण में:
- हम एक क्लास
ToUpper
को परिभाषित करते हैं जोargparse.Action
से विरासत में मिलती है। - जब तर्क का सामना होता है तो
__call__
विधि को कॉल किया जाता है। यह निम्नलिखित तर्क लेता है:parser
:ArgumentParser
ऑब्जेक्ट।namespace
: नेमस्पेस ऑब्जेक्ट जहाँ पार्स किए गए तर्क संग्रहीत होते हैं।values
: तर्क का मान।option_string
: विकल्प स्ट्रिंग जिसका उपयोग इस क्रिया को लागू करने के लिए किया गया था (जैसे,--name
)।
__call__
विधि के अंदर, हमvalues.upper()
का उपयोग करके मान को अपरकेस में परिवर्तित करते हैं और इसेsetattr(namespace, self.dest, values.upper())
का उपयोग करके नेमस्पेस में संग्रहीत करते हैं।- हम
parser.add_argument('--name', action=ToUpper, help='Name to convert to uppercase')
का उपयोग करके पार्सर में एक तर्क जोड़ते हैं। हमaction
तर्क को हमारी कस्टम एक्शन क्लास के रूप में निर्दिष्ट करते हैं।
इस स्क्रिप्ट को चलाने के लिए, आप इस तरह के कमांड का उपयोग करेंगे:
python your_script.py --name john
python your_script.py --cities london paris tokyo
कस्टम एक्शन क्लासेस के उपयोग के मामले
1. इनपुट को मान्य करना
आप इनपुट को मान्य करने और यदि इनपुट अमान्य है तो एक त्रुटि उत्पन्न करने के लिए कस्टम एक्शन क्लास का उपयोग कर सकते हैं। उदाहरण के लिए, आप एक एक्शन क्लास बना सकते हैं जो यह जाँचती है कि कोई फ़ाइल मौजूद है या नहीं या कोई संख्या एक विशिष्ट सीमा के भीतर है या नहीं।
import argparse
import os
class FileMustExist(argparse.Action):
def __call__(self, parser, namespace, values, option_string=None):
if not os.path.exists(values):
raise argparse.ArgumentTypeError(f'File not found: {values}')
setattr(namespace, self.dest, values)
parser = argparse.ArgumentParser(description='Example validating file existence.')
parser.add_argument('--input-file', action=FileMustExist, help='Path to input file.')
args = parser.parse_args()
print(f'Input file: {args.input_file}')
2. इकाइयों को परिवर्तित करना
आप इकाइयों को परिवर्तित करने के लिए कस्टम एक्शन क्लास का उपयोग कर सकते हैं। उदाहरण के लिए, आप एक एक्शन क्लास बना सकते हैं जो तापमान को सेल्सियस से फ़ारेनहाइट में परिवर्तित करती है।
3. जटिल डेटा संरचनाओं को संभालना
यदि आपको तर्कों को जटिल डेटा संरचनाओं (जैसे, शब्दकोश, वस्तुओं की सूची) में पार्स करने की आवश्यकता है, तो आप पार्सिंग तर्क को संभालने के लिए कस्टम एक्शन क्लास का उपयोग कर सकते हैं।
4. उदाहरण: समय क्षेत्रों को संभालना
एक ऐसे एप्लिकेशन पर विचार करें जिसे विभिन्न समय क्षेत्रों में तारीखों और समय को संभालने की आवश्यकता है। एक कस्टम एक्शन क्लास का उपयोग दिनांक स्ट्रिंग को पार्स करने और इसे pytz
जैसी पुस्तकालयों का उपयोग करके एक विशिष्ट समय क्षेत्र में परिवर्तित करने के लिए किया जा सकता है।
import argparse
import datetime
import pytz
class TimeZoneConverter(argparse.Action):
def __init__(self, option_strings, dest, timezone=None, **kwargs):
super().__init__(option_strings, dest, **kwargs)
self.timezone = timezone
def __call__(self, parser, namespace, values, option_string=None):
try:
dt = datetime.datetime.fromisoformat(values)
if self.timezone:
tz = pytz.timezone(self.timezone)
dt = tz.localize(dt)
setattr(namespace, self.dest, dt)
except ValueError:
raise argparse.ArgumentTypeError(f"Invalid date/time format. Use ISO format (YYYY-MM-DDTHH:MM:SS): {values}")
except pytz.exceptions.UnknownTimeZoneError:
raise argparse.ArgumentTypeError(f"Invalid Timezone: {self.timezone}")
parser = argparse.ArgumentParser(description='Example with timezone conversion.')
parser.add_argument('--event-time', action=TimeZoneConverter, timezone='America/Los_Angeles', help='Event time in ISO format (YYYY-MM-DDTHH:MM:SS). Converts to America/Los_Angeles timezone.')
args = parser.parse_args(['--event-time', '2024-10-27T10:00:00'])
print(f'Event Time (Los Angeles): {args.event_time}')
यह उदाहरण दिखाता है कि कैसे कस्टम एक्शन pytz
लाइब्रेरी का उपयोग करके समय क्षेत्र रूपांतरणों को संभाल सकते हैं, जो एक अधिक परिष्कृत उपयोग को प्रदर्शित करता है जो विश्व स्तर पर प्रासंगिक है।
एडवांस्ड आर्गपार्स का उपयोग करने के लिए सर्वोत्तम अभ्यास
- इसे सरल रखें: अपने सीएलआई को अत्यधिक जटिल न करें। सब-कमांड और कस्टम एक्शन का उपयोग केवल तभी करें जब आवश्यक हो।
- स्पष्ट सहायता संदेश प्रदान करें: प्रत्येक कमांड और तर्क के लिए स्पष्ट और संक्षिप्त सहायता संदेश लिखें।
add_argument()
मेंhelp
तर्क का बड़े पैमाने पर उपयोग करें। - इनपुट को मान्य करें: त्रुटियों और सुरक्षा कमजोरियों को रोकने के लिए हमेशा उपयोगकर्ता इनपुट को मान्य करें।
- संगत नामकरण परंपराओं का उपयोग करें: कमांड, तर्क और विकल्पों के लिए संगत नामकरण परंपराओं का पालन करें। लंबे विकल्प नामों के लिए कबाब-केस (
--my-option
) का उपयोग करने पर विचार करें। - पूरी तरह से परीक्षण करें: विभिन्न इनपुट और परिदृश्यों के साथ अपने सीएलआई का पूरी तरह से परीक्षण करें।
- अपने सीएलआई का दस्तावेजीकरण करें: अपने सीएलआई के लिए व्यापक दस्तावेज़ीकरण प्रदान करें, जिसमें प्रत्येक कमांड और तर्क का उपयोग कैसे करें इसके उदाहरण शामिल हैं। स्फिंक्स जैसे उपकरण आपके कोड से दस्तावेज़ीकरण उत्पन्न कर सकते हैं।
- स्थानीयकरण पर विचार करें: यदि आपका सीएलआई वैश्विक दर्शकों के लिए है, तो अपने सहायता संदेशों और अन्य उपयोगकर्ता-सामना करने वाले पाठ का स्थानीयकरण करने पर विचार करें।
निष्कर्ष
सब-कमांड और कस्टम एक्शन क्लास argparse
के साथ परिष्कृत और उपयोगकर्ता-अनुकूल सीएलआई बनाने के लिए शक्तिशाली उपकरण हैं। इन उन्नत सुविधाओं में महारत हासिल करके, आप मजबूत, रखरखाव योग्य और स्केलेबल कमांड-लाइन एप्लिकेशन बना सकते हैं जो एक विविध उपयोगकर्ता आधार की जरूरतों को पूरा करते हैं। बहु-भाषी अनुप्रयोगों के प्रबंधन से लेकर दुनिया भर में समय क्षेत्रों को संभालने तक, संभावनाएं विशाल हैं। अपनी पाइथन स्क्रिप्टिंग और कमांड-लाइन टूल विकास को अगले स्तर तक ले जाने के लिए इन तकनीकों को अपनाएं।